package com.cloudlead.common.worker.web;

import com.cloudlead.common.lang.annotation.RemoteService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.cglib.proxy.Enhancer;

import java.util.Set;

/**
 * Created by dean on 2015/8/2.
 */
public class RemoteServiceBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    private String scanBasePackage;

    public RemoteServiceBeanDefinitionRegistryPostProcessor(String scanBasePackage) {
        this.scanBasePackage = scanBasePackage;
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        try {
            Set<String> remoteServices = AnnotationScanHelper.scanClass(scanBasePackage, RemoteService.class);
            if (null != remoteServices) {
                for (String remoteService : remoteServices) {
                    Class remoteServiceClass = Class.forName(remoteService);
                    boolean containsBean = beanFactory.containsBean(remoteService);
                    if (!containsBean) {
                        Object instance = getRemoteServiceInstance(remoteServiceClass);
                        beanFactory.registerSingleton(getBeanName(remoteService), instance);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BeanInitializationException("Initialization remote service error", e);
        }
    }

    //首字母小写
    private String getBeanName(String remoteService) {
        return Character.toLowerCase(remoteService.charAt(0)) + remoteService.substring(1);
    }

    //使用cglib实现远程接口
    private Object getRemoteServiceInstance(Class remoteServiceClass) {
        Enhancer en = new Enhancer();
        // 设置要代理的目标类
        en.setSuperclass(Object.class);
        en.setInterfaces(new Class[]{remoteServiceClass});
        en.setCallback(new RemoteServiceProxy());
        return en.create();
    }

}
